package com.study.spring_aop_log.aop;


import com.study.spring_aop_log.service.LogService;
import com.sun.org.apache.bcel.internal.generic.ArrayElementValueGen;
import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@EnableAsync
public class OrderLogAspect {

    @Autowired
    private LogService logService;

    private long startTimeMillis=0;

    private long endTimeMillis=0;

    @Pointcut("@annotation(com.study.spring_aop_log.aop.OrderLogAnnotation)")
    public void logCut(){}


    @Before("logCut()")
    public void before(JoinPoint joinpoint){
        startTimeMillis=System.currentTimeMillis();
        doHandlerLog(joinpoint);
    }

    private void doHandlerLog(JoinPoint joinpoint) {
        System.out.println("/////////////////////");
        System.out.println(joinpoint.getStaticPart().toLongString()); //获得excution()
        String className = joinpoint.getTarget().getClass().getName();//获取方法所在类



//        logService.save();
        Object[] args = joinpoint.getArgs(); //得到对应方法的参数
        for (Object arg : args) {
            System.out.println(arg);
        }
        System.out.println("打印参数");
        //获取被拦截方法参数名列表
        MethodSignature signature = (MethodSignature) joinpoint.getSignature();

        Class aClass1 = signature.getDeclaringType(); //class com.study.spring_aop_log.controller.OrderGoodController
        String simpleName = aClass1.getSimpleName(); //控制器名称OrderGoodController
        Method method = signature.getMethod(); //获取调用的方法

        //**********************
        System.out.println(signature.getName()); //addTest
        String[] parameterNames1 = signature.getParameterNames();
        for (String s : parameterNames1) {
            System.out.println(s); //orderGood
        }
        //***********************
        System.out.println("----===----");



        LocalVariableTableParameterNameDiscoverer localVariableTable = new LocalVariableTableParameterNameDiscoverer();
        String[] parameterNames = localVariableTable.getParameterNames(method);
        for (String parameterName : parameterNames) {
            //获取参数列表 orderGood
            System.out.println(parameterName);
        }
        System.out.println("---======---");
        //使用SPEL进行key的解析
        ExpressionParser parser = new SpelExpressionParser();
        //SPEL上下文
        StandardEvaluationContext context = new StandardEvaluationContext();


        try {
            Class<?> aClass = Class.forName(className);
            Method[] declaredMethods = aClass.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println(declaredMethod.getName());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

//        ------------------- 获得注解 --------------------
//        MethodSignature signature = (MethodSignature) joinpoint.getSignature();
//        Method method = signature.getMethod(); //获取调用的方法
        //获得注解
        OrderLogAnnotation annotation = method.getAnnotation(OrderLogAnnotation.class);
        System.out.println(annotation.uid());
        System.out.println(annotation.msg());
        System.out.println(annotation.operation());

        System.out.println("===============");
//        ----------------------------------------
    }

    @Around(value = "logCut()")
    public Object around(ProceedingJoinPoint point){
        Signature signature = point.getSignature(); //void com.study.spring_aop_log.controller.OrderGoodController.add(OrderGood)
        System.out.println(signature);
        Object proceed = null;
        try {
            proceed = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }


}
